package com.tengju.bff.interfaces.manage.crm.crowd.facade;

import com.tengju.bff.interfaces.manage.crm.crowd.assembler.CrowdAssembler;
import com.tengju.bff.interfaces.manage.crm.crowd.vo.CrowdListForm;
import com.tengju.bff.interfaces.shared.ColumnVO;
import com.tengju.bff.interfaces.shared.KVVO;
import com.tengju.bff.interfaces.shared.TableAssembler;
import com.tengju.bff.interfaces.shared.TableVO;
import com.tengju.bff.interfaces.shared.servlet.ServletContextUtil;
import com.tengju.data.domain.model.analysis.Meta;
import com.tengju.data.domain.model.analysis.MetaHolder;
import com.tengju.data.domain.model.analysis.Row;
import com.tengju.data.domain.model.analysis.crowd.Tag;
import com.tengju.data.domain.model.clickhouse.CrowdAnalysisRepository;
import com.tengju.data.domain.model.cqrs.CrowdListFormQO;
import com.tengju.data.domain.shared.BasePage;
import com.tengju.data.domain.shared.CastUtil;
import com.tengju.user.application.archives.dto.PageQueryDTO;
import com.tengju.user.application.user.UserDocumentService;
import com.tengju.user.application.user.dto.UserSearchForm;
import com.tengju.user.domain.model.doc.UserDocument;
import com.tengju.user.domain.model.user.StarLevelEnum;
import com.tengju.user.domain.model.user.UserIdCode;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author chenhang
 * @Date 2021/5/6
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class CrowdAnalysisFacade extends PageQueryDTO {

    private final MetaHolder metaHolder;
    private final CrowdAnalysisRepository crowdAnalysisRepository;
    private final UserDocumentService userDocumentService;

    public TableVO list(CrowdListForm form) {
        List<UserIdCode> genSecIdCodes = form.getGenSecIdCodes();
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return null;
        }
        //生成table表头
        TableVO table = new TableVO();
        Collection<Meta> bizMetas = metaHolder.listMeta("crowd_detail").values();
        TableAssembler.buildColumns(table, bizMetas);
        table.addColumn(null, ColumnVO.of("showName", "用户", false));

        CrowdListFormQO qo = CrowdAssembler.toQO(genSecIdCodes, form);
        //查询表格数据
        BasePage<Row> pageRow = crowdAnalysisRepository.list(qo);
        List<Row> rows = pageRow.getDatas();
        if (CollectionUtils.isEmpty(rows)) {
            return null;
        }
        //封装默认的表格数据
        TableAssembler.buildData(table, rows, bizMetas, List.of("id_code"));

        //查询所属sec、ec、城市服务商的用户信息
        List<UserIdCode> idCodeList = rows.stream()
                .map(v -> v.getValue("id_code"))
                .map(v -> UserIdCode.of(CastUtil.castLong(v)))
                .collect(Collectors.toList());
        UserSearchForm userSearchForm = new UserSearchForm();
        userSearchForm.setIdCodes(idCodeList);
        List<UserDocument> userDocumentList = userDocumentService.batchSearchScroll(userSearchForm);
        Map<Long, UserDocument> userMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(userDocumentList)) {
            idCodeList = userDocumentList.stream()
                    .map(v -> List.of(
                            v.getIdCode(),
                            v.getOwnerCityIdCode(),
                            v.getOwnerEcIdCode(),
                            v.getOwnerGenSecIdCode())
                    )
                    .flatMap(Collection::stream)
                    .map(UserIdCode::of)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            userSearchForm.setIdCodes(idCodeList);
            userSearchForm.setScrollId(null);
            userDocumentList = userDocumentService.batchSearchScroll(userSearchForm);
            if (!CollectionUtils.isEmpty(userDocumentList)) {
                userMap = userDocumentList.stream()
                        .collect(Collectors.toMap(UserDocument::getIdCode, v -> v, (v1, v2) -> v1));
            }
        }
        if (CollectionUtils.isEmpty(table.getRecords())) {
            return null;
        }

        //封装table额外的信息
        for (Map<String, Object> record : table.getRecords()) {
            Long idCode = CastUtil.castLong(record.get("id_code"));
            UserDocument userDocument = userMap.get(idCode);
            Long ownerCityIdCode = 0L;
            Long ownerEcIdCode = 0L;
            Long ownerGenSecIdCode = 0L;
            if (userDocument != null) {
                ownerCityIdCode = userDocument.getOwnerCityIdCode();
                ownerEcIdCode = userDocument.getOwnerEcIdCode();
                ownerGenSecIdCode = userDocument.getOwnerGenSecIdCode();
            }
            UserDocument ownerCityDocument = userMap.get(ownerCityIdCode);
            UserDocument ownerEcDocument = userMap.get(ownerEcIdCode);
            UserDocument ownerGenSecDocument = userMap.get(ownerGenSecIdCode);
            record.put("idCode", idCode);
            record.put("ownerCityIdCode", ownerCityIdCode);
            record.put("ownerEcIdCode", ownerEcIdCode);
            record.put("ownerGenSecIdCode", ownerGenSecIdCode);
            record.put("belong_service_provider", genShowName(ownerCityDocument));
            record.put("belong_ec", genShowName(ownerEcDocument));
            record.put("belong_gen_sec", genShowName(ownerGenSecDocument));
            record.put("showName", genShowName(userDocument));
        }
        table.page(pageRow.getTotal(), form.getPageIndex(), form.getPageSize());
        return table;
    }

    public String genShowName(UserDocument userDocument) {
        if (userDocument == null) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        sb.append(userDocument.getNickName()).append(" ")
                .append(StarLevelEnum.parseByCode(userDocument.getStarLevel()).getShortName()).append(" ")
                .append("(").append(userDocument.getIdCode()).append(")");
        return sb.toString();
    }


    public List<KVVO> tagList() {
        List<UserIdCode> genSecIdCodes = ServletContextUtil.getServletContext().getGenSecIdCodes();
        List<Row> sqlRows = crowdAnalysisRepository.tagList(genSecIdCodes);
        List<KVVO> result = new ArrayList<>();
        Map<Tag, Integer> tagCountMap = new HashMap<>();
        for (Row row : sqlRows) {
            String tagName = CastUtil.castString(row.getValue("tag_name"));
            String tagValue = CastUtil.castString(row.getValue("tag_value"));
            Tag tag = Tag.parse(tagName, tagValue);
            int count = CastUtil.castInt(row.getValue("cnt"));
            tagCountMap.put(tag, count);
        }
        for (Tag tag : Tag.values()) {
            result.add(KVVO.of(tag, tagCountMap.getOrDefault(tag, 0)));
        }
        return result;
    }
}
